package com.sinszm.web;


import com.google.gson.Gson;
import com.sinszm.web.annotation.Ws;
import com.sinszm.web.exception.GlobalErrorPageInterceptor;
import com.sinszm.web.interceptor.MRequestInterceptor;
import com.sinszm.web.properties.WebProperties;
import com.sinszm.web.properties.WebSocketProperties;
import com.sinszm.web.request.MRequestFilter;
import com.sinszm.web.socket.MWebSocketHandler;
import com.sinszm.web.socket.MWebSocketInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * SzmWeb自动配置
 *
 * @author chenjianbo
 */
@ServletComponentScan(basePackageClasses = {MRequestFilter.class})
@EnableConfigurationProperties({WebSocketProperties.class, WebProperties.class})
public class SzmWebAutoConfiguration implements WebMvcConfigurer {

    private final Gson gson;

    private final WebProperties webProperties;

    private static final String[] EXCLUDE_URI = {"/favicon.ico", "/error"};

    @Autowired
    public SzmWebAutoConfiguration(
            Gson gson,
            WebProperties webProperties) {
        this.gson = gson;
        this.webProperties = webProperties;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //请求日志拦截
        List<String> patterns = ObjectUtils.isEmpty(webProperties.getPatterns()) ? Collections.singletonList("/**") : webProperties.getPatterns();
        List<String> ePatterns = ObjectUtils.isEmpty(webProperties.getExcludePatterns()) ? new ArrayList<>() : webProperties.getExcludePatterns();
        ePatterns.addAll(Arrays.asList(EXCLUDE_URI));
        registry.addInterceptor(new MRequestInterceptor(gson)).addPathPatterns(patterns).excludePathPatterns(ePatterns);
        //系统错误异常日志拦截
        registry.addInterceptor(new GlobalErrorPageInterceptor());
    }

    /**
     * WebSocket配置
     */
    @Ws
    @EnableWebSocket
    public static class SzmWebSocketConfiguration implements WebSocketConfigurer {

        private final WebSocketProperties properties;
        private final ApplicationContext context;

        @Autowired
        public SzmWebSocketConfiguration(WebSocketProperties properties, ApplicationContext context) {
            this.properties = properties;
            this.context = context;
        }

        @Override
        public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
            List<String> uri = properties.getUri();
            registry.addHandler(
                    new MWebSocketHandler(context, properties),
                    uri.toArray(new String[0])
            ).setAllowedOrigins("*")
                    .addInterceptors(new MWebSocketInterceptor());
            //添加对SockJs的支持
            List<String> jsUri = properties.getJsUri();
            if (jsUri != null && jsUri.size() > 0) {
                registry.addHandler(
                        new MWebSocketHandler(context, properties),
                        jsUri.toArray(new String[0])
                ).setAllowedOrigins("*")
                        .addInterceptors(new MWebSocketInterceptor()).withSockJS();
            }
        }

    }

}
